import bean.PickUpConstant;

import java.lang.reflect.Method;
import java.util.*;

/**
 * @Author:hihuzi 2018/5/1 11:09
 */
public class PickUpUtil implements PickUpFactory {

    /**
     * TODO List<T> 提取特定的 属性值 返回 List<Map>
     *
     * @Author:hihuzi 2018/4/30 15:49
     */
    @Override
    public <T> List<Map> pickUp(List<T> objList, String... strs) throws Exception {

        return pickUp(objList, PickUpConstant.DiyKeyStyle.setKey(2), strs);
    }

    /**
     * TODO List<T> 提取特定的 属性值 返回 List<value>
     *
     * @Author:hihuzi 2018/4/30 15:49
     */
    @Override
    public <T> Set<String> pickUpSet(List<T> objList, String... strs) throws Exception {

        return pickUpSet(objList, PickUpConstant.ValueIsNullGiveUp, strs);
    }

    /**
     * TODO T 提取特定的 属性值 返回 List<value>
     *
     * @Author:hihuzi 2018/4/30 15:49
     */
    @Override
    public <T> List<String> pickUpList(T obj, List<String> strs) throws Exception {

        return batchpickupList(obj, strs, PickUpConstant.ValueIsNullGiveUp);
    }
//TODO 方法实现

    public static <T> Set<String> pickUpSet(List<T> objsList, PickUpConstant bean, String... strs) throws Exception {

        if (objsList == null || objsList.size() == 0)
            throw new IndexOutOfBoundsException("调用pickUpSimple: 输入的是null 或者 List大小为0");
        Class<?> clazz = objsList.get(0).getClass();
        Set<String> list = new HashSet<>(objsList.size());//初始化同样大小list
        for (T obj: objsList) {
            Map<String, String> m = new HashMap<>(strs.length);//初始化同样大小map
            for (String str: strs) {
                Object invoke = getObject(clazz, (T) obj, str);
                if (1 == bean.getKey() && invoke != null) {// TODO 空值舍弃
                    list.add(invoke.toString());
                }
            }
        }
        return list;
    }


    public static <T> List<Map> pickUp(List<T> objsList, PickUpConstant bean, String... strs) throws Exception {

        if (objsList == null || objsList.size() == 0)
            throw new IndexOutOfBoundsException("调用pickUpSimple: 输入的是null 或者 List大小为0");
        Class<?> clazz = objsList.get(0).getClass();
        List<Map> result = new ArrayList<>(objsList.size());//初始化同样大小list
        for (T obj: objsList) {
            Map map = new HashMap<>(strs.length);//初始化同样大小map
            for (String str: strs) {
                Object invoke = getObject(clazz, (T) obj, str);
                map = getDiyKeyStyle(bean, map, str, invoke);
            }
            result.add(map);
        }
        return result;
    }


    public static <T> List<String> batchpickupList(T obj, List<String> strs, PickUpConstant bean) throws Exception {

        if (obj == null)
            throw new IndexOutOfBoundsException("调用pickUpSimple: 输入的是null");
        Class<?> clazz = obj.getClass();
        List<String> list = new ArrayList<>();
        for (String str: strs) {
            Object invoke = getObject(clazz, (T) obj, str);
            if (1 == bean.getKey() && invoke != null) {
                list.add(invoke.toString());
            } else {
                list.add("");
            }
        }
        return list;
    }

    //TODO 公共方法

    private static <T> Object getObject(Class<?> clazz, T obj, String str) {

        StringBuffer name = new StringBuffer();
        name.append("get").append(str.substring(0, 1).toUpperCase()).append(str.substring(1));
        Method method = null;
        Object invoke = null;
        try {
            method = clazz.getMethod(name.toString());
            invoke = method.invoke(obj);
        } catch (Exception e) {
        }
        return invoke;
    }

    private static Map getDiyKeyStyle(PickUpConstant bean, Map map, String str, Object invoke) {

        switch (bean) {
            case ValueIsNullGiveUp:
                if (invoke != null)
                    map.put(str, invoke);
                break;
            case WrongAttributeToEmpty:
                if (invoke != null)
                    map.put(str, invoke);
                else
                    map.put(str, "");
                break;
            case DiyKeyStyle:
                if (bean.getKey() == 1)
                    if (invoke != null)
                        map.put(new StringBuffer().append(str.substring(0, 1).toUpperCase()).append(str.substring(1).toLowerCase()), invoke);
                    else
                        map.put(new StringBuffer().append(str.substring(0, 1).toUpperCase()).append(str.substring(1).toLowerCase()), "");
                if (bean.getKey() == 2)
                    if (invoke != null)
                        map.put(new StringBuffer().append(str.toLowerCase()), invoke);
                    else
                        map.put(new StringBuffer().append(str.toLowerCase()), "");
                if (bean.getKey() == 3)
                    if (invoke != null)
                        map.put(new StringBuffer().append(str.substring(0, 1).toUpperCase()).append(str.substring(1).toLowerCase()), invoke);
                    else
                        map.put(new StringBuffer().append(str.substring(0, 1).toUpperCase()).append(str.substring(1).toLowerCase()), "");
                break;
        }
        return map;
    }

}

